{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Modify chip options"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When creating a new design using Qiskit Metal, a default set of information related to the chip is specified. This includes chip size, which defines the active simulation area in the electromagnetic simulator of your choice. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this notebook we will see how to access and change some of these chip-related specifications to allow you the flexibility of designing your custom quantum chip. We will start by drawing a simple planar design, and then we will play around with chip parameters to highlight the different features accessible through the API."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For convenience, let's begin by enabling [automatic reloading of modules](https://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html?highlight=autoreload) when they change."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, let's import Qiskit Metal:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import qiskit_metal as metal\n",
    "from qiskit_metal import designs, draw\n",
    "from qiskit_metal import Dict, open_docs\n",
    "\n",
    "%metal_heading Welcome to Qiskit Metal!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us draw our simple planar design: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design = designs.DesignPlanar()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Select a QComponent to create (The QComponent is a python class named `TransmonPocket`)\n",
    "from qiskit_metal.qlibrary.qubits.transmon_pocket import TransmonPocket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a new qcomponent object with name 'Q1' \n",
    "q1 = TransmonPocket(design, 'Q1')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that we have defined a simple planar design, we can use the following commands to access the dictionary keys to locate a chip and then access the chip-related parameters avaialble to be modified:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.chips.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.chips.main"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here, we can see there are four different parameters available for us to change:\n",
    "- Material\n",
    "- Layer_start\n",
    "- Layer_end\n",
    "- Size"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you want to change your wafer material from silicon to germanium, for example, you can run the following code block: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.chips.main.material = ['germanium']\n",
    "design.rebuild()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, if we check our chip parameters again, we will see a different item under material. Let's try it out!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.chips.main"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now know how to modify the arguments related to the chip. The most common parameter we may find ourselves dealing with is the chip size. Once we have an idea about our experimental design, choosing a chip size that allows us sufficent space to place all the components as desired is important. Here are the different parameters related to the chip size. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.chips.main.size"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The parameters 'sample_holder_top' and 'sample_holder_bottom' are placeholders for parameters that specify the top and bottom coordinates of the 'vacuum box' in a multilevel system. The other parameters are self-explanatory. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, let us play around with chip-size and export these files to GDS to look at the effects of our commands. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# We will begin by resetting the wafer material to silicon\n",
    "\n",
    "design.chips.main.material = ['silicon']\n",
    "design.rebuild()\n",
    "\n",
    "# We will then export the current file to a GDS file\n",
    "a_gds = design.renderers.gds\n",
    "a_gds.options['path_filename'] = '../../resources/Fake_Junctions.GDS'\n",
    "\n",
    "design.renderers.gds.export_to_gds(\"Before_size_change.gds\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we will change the size of the chip in x and y dimensions, and then export it as a second GDS file. This can be done as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.chips.main.size['size_x'] = '15mm'\n",
    "design.chips.main.size['size_y'] = '10mm'\n",
    "design.rebuild()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.renderers.gds.export_to_gds(\"After_size_x_y_change.gds\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will now move the center of the chip and see the effect it has on the qubit design. We will export this change as a third GDS file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# First we will rest to the original settings\n",
    "\n",
    "design.chips.main.size['size_x'] = '9mm'\n",
    "design.chips.main.size['size_y'] = '6mm'\n",
    "\n",
    "# Next we will shift the center of the chip\n",
    "\n",
    "design.chips.main.size['center_x'] = '4.5mm'\n",
    "design.chips.main.size['center_y'] = '2mm'\n",
    "design.rebuild()\n",
    "\n",
    "# We next export it to GDS\n",
    "\n",
    "design.renderers.gds.export_to_gds(\"After_center_x_y_change.gds\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now is a good time to take a look at the three GDS files we have created so far. In our previous run we intentionally centered the chip such that the entire device is not on the chip. This triggers a warning and enables you to make a correction. \n",
    "\n",
    "This warning is triggered by no-cheese check which is always 'ON' by default for the 'main' chip and for level '1'. Cheesing is the process of adding flux holes to the wafer to allow access to the ground plane. So, no_cheese is the “keep-out” region on the chip where the holes would not be implemented. If you have a multiple chip device, this option needs to be modified to match your configuration. We will see how to access and change this setting below. We first look at the GDS rendering options."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a_gds.options"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We notice the dictionary called 'cheese' and 'no_cheese' above. We are interested in the 'view_in_file' option. We show how to access this option below. For a multilayer device, each chip and layer needs to be set to 'True'. If this 'view_in_file' check is 'False', we will not see the warning message we saw above. Let us try it out!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a_gds.options.no_cheese['view_in_file']['main']={1: False}\n",
    "a_gds.options.cheese['view_in_file']['main']={1: False}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now when we export to GDS, we do not see a warning message."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.renderers.gds.export_to_gds(\"After_center_x_y_change_no_warning.gds\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we revert back the 'cheese' and 'no_cheese' dictionaries and overwrite our last GDS with a modified one so that the device is within the chip."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Restore a_gds options\n",
    "\n",
    "a_gds.options.no_cheese['view_in_file']['main']={1: True}\n",
    "a_gds.options.cheese['view_in_file']['main']={1: True}\n",
    "\n",
    "# We will shift the center of the chip to origin\n",
    "\n",
    "design.chips.main.size['center_x'] = '0mm'\n",
    "design.chips.main.size['center_y'] = '0mm'\n",
    "design.rebuild()\n",
    "\n",
    "# We next export it to GDS\n",
    "\n",
    "design.renderers.gds.export_to_gds(\"After_reverting_x_y_change.gds\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You have now restored the chip to its original configuration!"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
